package com.platform.file.controller;

import cn.hutool.core.date.StopWatch;
import com.alibaba.fastjson.JSONObject;
import com.platform.common.core.domain.R;
import com.platform.common.core.utils.DateUtils;
import com.platform.common.core.utils.StringUtils;
import com.platform.common.core.utils.file.FileUtils;
import com.platform.common.core.web.controller.BaseController;
import com.platform.common.core.web.domain.AjaxResult;
import com.platform.common.redis.service.RedisService;
import com.platform.common.security.utils.AESUtil_SC;
import com.platform.file.config.MinioConfig;
import com.platform.file.constant.SysFileConstants;
import com.platform.file.model.SysFile;
import com.platform.file.model.SysFileDto;
import com.platform.file.service.IDicFileLogService;
import com.platform.file.service.ISysFileService;
import com.platform.file.utils.FileUploadUtils;
import com.platform.file.utils.MinioUtils;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.*;

@Slf4j
@RestController
@RequestMapping("/fileCenter/")
public class FileMinioController extends BaseController {
    private static final Logger log = LoggerFactory.getLogger(SysFileController.class);
    @Autowired
    private ISysFileService sysFileService;
    @Autowired
    private RedisService redisService;
    @Autowired
    private IDicFileLogService fileLogService;

    @Autowired
    MinioConfig minioConfig;

    @Autowired
    MinioUtils minioUtils;

   /* @Value("${minio.fileCenterPrefix}")
    public String filePrefix;*/

    @Value("${minio.bucketName}")
    public String bucketName;

    /**
     * 上传文件（返回文件加密后的路径）
     * @param file   文件
     * @param serviceName   服务名称
     * @param type       文件存储分区：3=内部公开文件夹(需要走平台认证，仅限内部人访问，文件无权限),
     *                              2=公开文件(不需要走平台认证)
     *                              1=部门级文件夹(需要走平台认证,部门文档,有权限，有权限)
     *                              0=私有文件(适合小团队或者个人文档)
     * @param bucketName  存储桶(默认可不填)
     * @param fileTag     文件标签(0=其他，1=报关单，2=邮件类文件,3=板车垫板,4=报告,5=鉴定报告,6=设备维修，7=通知与新闻，8=异常上报......按模块定义好)
     * @return
     */
    @PostMapping("/upload")
    public R<SysFile> upload(MultipartFile file, @RequestParam(name = "serviceName") String serviceName, String type,String bucketName,String fileTag)
    {
        if(file==null||file.getSize()==0){
            return R.fail("请上传文件");
        }
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        String cataloguePrefix= SysFileConstants.BUCKET_MAP.get(type);
        if(StringUtils.isEmpty(cataloguePrefix)){
            //默认公共文件
            cataloguePrefix=SysFileConstants.PUBLIC;
        }
        if(StringUtils.isEmpty(serviceName)){
            serviceName= SysFileConstants.SERVICENAME_SYS;
        }
        /**文件标签，默认其他*/
        if(StringUtils.isEmpty(fileTag)){
            fileTag= SysFileConstants.FILETAG_OTHER;
        }

        String url="";
        //String returnPath =filePrefix+'/';
        String fileUrlSecret="";
        try
        {
            // 上传并返回访问地址
            url = sysFileService.uploadByBucketName(file, serviceName,cataloguePrefix,bucketName);
            SysFile sysFile = new SysFile();
            sysFile.setName(FileUtils.getName(url));
            if(org.apache.commons.lang3.StringUtils.isEmpty(bucketName)){
                bucketName=minioConfig.getBucketName();
            }
            fileUrlSecret=AESUtil_SC.encryptNoBase64(bucketName+"/"+url,SysFileConstants.FILESECRET);
            sysFile.setUrl(fileUrlSecret);
            return R.ok(sysFile);
        }
        catch (Exception e)
        {
            log.error("上传文件失败", e);
            return R.fail(e.getMessage());
        }finally {
            fileLogService.saveUploadLogNew(serviceName,file,url,bucketName,fileUrlSecret,cataloguePrefix,fileTag);
            stopWatch.stop();
            log.info("上传文件名的路径为{},上传耗时{}秒",url,stopWatch.getTotalTimeSeconds());
        }
    }
    /**
     * 上传文件（返回文件加密后的路径）
     * @param files   文件
     * @param serviceName   服务名称
     * @param type       文件存储分区：3=内部公开文件夹(需要走平台认证，仅限内部人访问，文件无权限),
     *                              2=公开文件(不需要走平台认证)
     *                              1=部门级文件夹(需要走平台认证,部门文档,有权限，有权限)
     *                              0=私有文件(适合小团队或者个人文档)
     * @param bucketName  存储桶(默认可不填)
     * @param fileTag     文件标签(0=其他，1=报关单，2=邮件类文件,3=板车垫板,4=报告,5=鉴定报告,6=设备维修，7=通知与新闻，8=异常上报......按模块定义好)
     * @return
     */

    @PostMapping("/uploadByBase64")
    public R<SysFile> uploadByBase64(@RequestBody Map<String, String> files, @RequestParam(name = "serviceName") String serviceName, @RequestParam(name = "type")  String type, String bucketName, @RequestParam(name = "fileTag") String fileTag)
    {

        if (files == null||files.size()==0) {
            return  R.fail("上传文件不能为空");
        }
        double reSize=0;
        String fileName = files.get("name");
        String base64Str = files.get("data");
        reSize = this.getFileSize(base64Str);
        if (base64Str != null && base64Str.contains(",")) {
            base64Str = base64Str.split(",")[1];
        }
        Base64.Decoder decoder = Base64.getDecoder();
        byte[] decode = decoder.decode(base64Str);
        ByteArrayInputStream bArray = new ByteArrayInputStream(decode);


        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        String cataloguePrefix= SysFileConstants.BUCKET_MAP.get(type);
        if(StringUtils.isEmpty(cataloguePrefix)){
            //默认公共文件
            cataloguePrefix=SysFileConstants.PUBLIC;
        }
        if(StringUtils.isEmpty(serviceName)){
            serviceName= SysFileConstants.SERVICENAME_SYS;
        }
        /**文件标签，默认其他*/
        if(StringUtils.isEmpty(fileTag)){
            fileTag= SysFileConstants.FILETAG_OTHER;
        }

        String url="";
        //String returnPath =filePrefix+'/';
        String fileUrlSecret="";
        try
        {
            // 上传并返回访问地址
            url = sysFileService.uploadByBase64(fileName,bArray, serviceName,cataloguePrefix,bucketName);
            SysFile sysFile = new SysFile();
            sysFile.setName(FileUtils.getName(url));
            if(org.apache.commons.lang3.StringUtils.isEmpty(bucketName)){
                bucketName=minioConfig.getBucketName();
            }
            fileUrlSecret=AESUtil_SC.encryptNoBase64(bucketName+"/"+url,SysFileConstants.FILESECRET);
            sysFile.setUrl(fileUrlSecret);
            return R.ok(sysFile);
        }
        catch (Exception e)
        {
            log.error("上传文件失败", e);
            return R.fail(e.getMessage());
        }finally {
            fileLogService.saveUploadLogNew(serviceName,url,reSize,bucketName,fileUrlSecret,cataloguePrefix,fileTag);
            stopWatch.stop();
            log.info("上传文件名的路径为{},上传耗时{}秒",url,stopWatch.getTotalTimeSeconds());
        }
    }

    /**
     * 批量上传文件（返回文件加密后的路径）
     * @param files   文件
     * @param serviceName   服务名称
     * @param type       文件存储分区：3=内部公开文件夹(需要走平台认证，仅限内部人访问，文件无权限),
     *                              2=公开文件(不需要走平台认证)
     *                              1=部门级文件夹(需要走平台认证,部门文档,有权限，有权限)
     *                              0=私有文件(适合小团队或者个人文档)
     * @param bucketName  存储桶(默认可不填)
     * @param fileTag     文件标签(0=其他，1=报关单，2=邮件类文件,3=板车垫板,4=报告,5=鉴定报告,6=设备维修，7=通知与新闻，8=异常上报......按模块定义好)
     * @return
     */
    @PostMapping("/bathUploadFile")
    public R<List<SysFile>> bathUploadFile(@RequestParam("files") MultipartFile[] files, @RequestParam(name = "serviceName") String serviceName, String type,String bucketName,String fileTag)
    {
        if(files==null){
            return R.fail("请上传文件");
        }
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        String cataloguePrefix= SysFileConstants.BUCKET_MAP.get(type);
        if(StringUtils.isEmpty(cataloguePrefix)){
            //默认公共文件
            cataloguePrefix=SysFileConstants.PUBLIC;
        }
        if(StringUtils.isEmpty(serviceName)){
            serviceName= SysFileConstants.SERVICENAME_SYS;
        }
        /**文件标签，默认其他*/
        if(StringUtils.isEmpty(fileTag)){
            fileTag= SysFileConstants.FILETAG_OTHER;
        }
        String url="";
        String fileUrlSecret="";
        try
        {
            List<SysFile> sysFileList=new ArrayList<>();
            for (int i=0;i<files.length;i++){
                // 上传并返回访问地址
                url = sysFileService.uploadByBucketName(files[i], serviceName,cataloguePrefix,bucketName);
                SysFile sysFile = new SysFile();
                sysFile.setName(FileUtils.getName(url));
                if(org.apache.commons.lang3.StringUtils.isEmpty(bucketName)){
                    bucketName=minioConfig.getBucketName();
                }
                fileUrlSecret=AESUtil_SC.encryptNoBase64(bucketName+"/"+url,SysFileConstants.FILESECRET);
                sysFile.setUrl(fileUrlSecret);
                fileLogService.saveUploadLogNew(serviceName,files[i],url,bucketName,fileUrlSecret,cataloguePrefix,fileTag);
            }
            return R.ok(sysFileList);
        }
        catch (Exception e)
        {
            log.error("上传文件失败", e);
            return R.fail(e.getMessage());
        }finally {
            stopWatch.stop();
            log.info("上传文件名的路径为{},上传耗时{}秒",url,stopWatch.getTotalTimeSeconds());
        }
    }

    /**
     * 上传文件（返回文件加密后的路径）(自定义文件名)
     * @param file   文件
     * @param serviceName   服务名称
     * @param type       文件存储分区：3=内部公开文件夹(需要走平台认证，仅限内部人访问，文件无权限),
     *                              2=公开文件(不需要走平台认证)
     *                              1=部门级文件夹(需要走平台认证,部门文档,有权限，有权限)
     *                              0=私有文件(适合小团队或者个人文档)
     * @param bucketName  存储桶(默认可不填)
     * @param fileTag     文件标签(0=其他，1=报关单，2=邮件类文件,3=板车垫板,4=报告,5=鉴定报告,6=设备维修，7=通知与新闻，8=异常上报，9=交接，10=分拣清点，11=入库称重、组板调货......按模块定义好)
     * @return
     */
    @PostMapping("/uploadByFileName")
    public R<SysFile> uploadByFileName(MultipartFile file, @RequestParam(name = "serviceName") String serviceName,@RequestParam(name = "fileName") String fileName, String type,String bucketName,String fileTag)
    {
        if(file==null||file.getSize()==0){
            return R.fail("请上传文件");
        }
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        String cataloguePrefix=SysFileConstants.BUCKET_MAP.get(type);
        if(StringUtils.isEmpty(cataloguePrefix)){
            //默认公共文件
            cataloguePrefix=SysFileConstants.PUBLIC;
        }
        if(StringUtils.isEmpty(serviceName)){
            serviceName= SysFileConstants.SERVICENAME_SYS;
        }

        /**文件标签，默认其他*/
        if(StringUtils.isEmpty(fileTag)){
            fileTag= SysFileConstants.FILETAG_OTHER;
        }

        String url="";
        //String returnPath =filePrefix+'/';
        url = cataloguePrefix + "/"  + serviceName + "/"+ DateUtils.dateTimeNow("yyyy/MM/dd")+"/" +fileName;
        String fileUrlSecret="";
        try
        {
            //异步调用文件上传
            try {
                sysFileService.uploadByAsyncFileNameAndBucketName(file.getInputStream(),url,file.getContentType(),bucketName);
            } catch (Exception e) {
                e.printStackTrace();
            }
            // 上传并返回访问地址
            SysFile sysFile = new SysFile();
            sysFile.setName(FileUtils.getName(url));
            if(org.apache.commons.lang3.StringUtils.isEmpty(bucketName)){
                bucketName=minioConfig.getBucketName();
            }
            fileUrlSecret=AESUtil_SC.encryptNoBase64(bucketName+"/"+url,SysFileConstants.FILESECRET);
            sysFile.setUrl(fileUrlSecret);
            return R.ok(sysFile);
        }
        catch (Exception e)
        {
            log.error("上传文件失败", e);
            return R.fail(e.getMessage());
        }finally {
            fileLogService.saveUploadLogNew(serviceName,file,url,bucketName,fileUrlSecret,cataloguePrefix,fileTag);
            stopWatch.stop();
            log.info("上传文件名的路径为{},上传耗时{}秒",url,stopWatch.getTotalTimeSeconds());
        }
    }
    /**
     * 上传文件
     * @param
     * @param
     * @return
     */
    @PostMapping("/testdoc")
    public R<List<String>> testdoc(MultipartFile[] files,@RequestParam(name = "serviceName")  String serviceName,String type,String fileTag) throws Exception {
        SysFileDto sysFileDto = new SysFileDto();
        List<Map<String, String>> fileList = new ArrayList<>();
        for (MultipartFile file : files) {
            try {
                InputStream inputStream = file.getInputStream();
                Map<String, String> map = new HashMap<>();
                map.put("data", inputStream2Base64(inputStream));
                String originalFilename = file.getOriginalFilename();
                map.put("name",originalFilename);
                fileList.add(map);
            } catch (Exception e) {
                e.printStackTrace();
            }finally {

            }
        }
        sysFileDto.setFileTag(type);
        sysFileDto.setFileTag(fileTag);
        sysFileDto.setFiles(fileList);
        sysFileDto.setServiceName(serviceName);
        return uploadFile(sysFileDto);
    }

    /**
     * 上传文件
     * @param
     * @param
     * @return
     */
    @PostMapping("/uploadFile")
    public R<List<String>> uploadFile(@RequestBody SysFileDto dto) {
        if(dto==null){
            return  R.fail("上传文件不能为空");
        }
        String type=dto.getType();
        String cataloguePrefix=SysFileConstants.BUCKET_MAP.get(type);
        if(StringUtils.isEmpty(cataloguePrefix)){
            //默认公共文件
            cataloguePrefix=SysFileConstants.PUBLIC;
        }

        String fileTag=dto.getFileTag();
        /**文件标签，默认其他*/
        if(StringUtils.isEmpty(dto.getFileTag())){
            fileTag= SysFileConstants.FILETAG_OTHER;
        }

        String serviceName=dto.getServiceName();
        List<Map<String, String>> files=dto.getFiles();
        if(StringUtils.isEmpty(serviceName)){
            serviceName=SysFileConstants.SERVICENAME_SYS;
        }
        if (files == null||files.size()==0) {
            return  R.fail("上传文件不能为空");
        }
        R<List<String>> result = R.ok();
        List<String> filePathList = new ArrayList<>();
        //String returnPath =filePrefix+'/';
        for (int i = 0; i < files.size(); i++) {
            String filePath="";
            double reSize=0;
            String fileUrlSecret="";
            try {
                Map<String, String> file = files.get(i);
                String fileName = file.get("name");
                String base64Str = file.get("data");
                //判断文件大小是否超过20MB
                reSize = this.getFileSize(base64Str);
                if ((reSize / 1024 / 1024) > SysFileConstants.FILE_MAX_VALUE) {
                    return R.fail(R.FAIL,"文件大小不能超过20MB，请重新上传");
                }
                String contentType=getcontentType(fileName);
                if (base64Str != null && base64Str.contains(",")) {
                    base64Str = base64Str.split(",")[1];
                }
                Base64.Decoder decoder = Base64.getDecoder();
                byte[] decode = decoder.decode(base64Str);
                ByteArrayInputStream bArray = new ByteArrayInputStream(decode);
                filePath = cataloguePrefix + "/" + serviceName + "/" + System.currentTimeMillis() + "_" + fileName;
                String uploadFilePath = sysFileService.uploadFile(filePath, bArray,contentType);
                uploadFilePath=minioConfig.getBucketName()+"/"+uploadFilePath;
                fileUrlSecret=AESUtil_SC.encryptNoBase64(uploadFilePath,SysFileConstants.FILESECRET);
                filePathList.add(fileUrlSecret);
            } catch (Exception e) {
                e.printStackTrace();
                log.error("上传文件失败", e);
                return R.fail(e.getMessage());
            }finally {
                fileLogService.saveUploadLogNew(serviceName,filePath,reSize,minioConfig.getBucketName(),fileUrlSecret,cataloguePrefix,fileTag);
            }
        }
        result.setData(filePathList);
        return result;
    }


    /**
     * 返回全路径
     */
    @PostMapping("/uploadAllUrl")
    public R<SysFile> uploadAllUrl(MultipartFile file, @RequestParam(name = "serviceName") String serviceName, String type,String bucketName,String fileTag)
    {
        if(file==null||file.getSize()==0){
            return R.fail("请上传文件");
        }
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        String cataloguePrefix= SysFileConstants.BUCKET_MAP.get(type);
        if(StringUtils.isEmpty(cataloguePrefix)){
            //默认公共文件
            cataloguePrefix=SysFileConstants.PUBLIC;
        }
        if(StringUtils.isEmpty(serviceName)){
            serviceName= SysFileConstants.SERVICENAME_SYS;
        }
        /**文件标签，默认其他*/
        if(StringUtils.isEmpty(fileTag)){
            fileTag= SysFileConstants.FILETAG_OTHER;
        }

        String url="";
        //String returnPath =filePrefix+'/';
        String fileUrlSecret="";
        try
        {
            // 上传并返回访问地址
            url = sysFileService.uploadByBucketName(file, serviceName,cataloguePrefix,bucketName);
            SysFile sysFile = new SysFile();
            sysFile.setName(FileUtils.getName(url));
            if(org.apache.commons.lang3.StringUtils.isEmpty(bucketName)){
                bucketName=minioConfig.getBucketName();
            }
            fileUrlSecret=AESUtil_SC.encryptNoBase64(bucketName+"/"+url,SysFileConstants.FILESECRET);
            sysFile.setUrl(fileUrlSecret);
            return R.ok(sysFile);
        }
        catch (Exception e)
        {
            log.error("上传文件失败", e);
            return R.fail(e.getMessage());
        }finally {
            fileLogService.saveUploadLogNew(serviceName,file,url,bucketName,fileUrlSecret,cataloguePrefix,fileTag);
            stopWatch.stop();
            log.info("上传文件名的路径为{},上传耗时{}秒",url,stopWatch.getTotalTimeSeconds());
        }
    }

    /**
     * 获取文件流(前端预览或下载)
     * @param fileUrl   文件加密路径
     * @param type    type=1 预览，2=下载
     * @return
     */
    @RequestMapping("/previewFileNew")
    public void previewFileNew(@RequestParam("fileUrl") String fileUrl,String type, HttpServletResponse response){
        //参数校验
        try {
            if(StringUtils.isEmpty(fileUrl)){
                returnResponseResult(response,R.FAIL,"文件路径不能为空");
            }else {
                try {
                    String minioPath= AESUtil_SC.decryptNoBase64(fileUrl,SysFileConstants.FILESECRET);
                    String bucketName= FileUploadUtils.getBucketName(minioPath);
                    if(StringUtils.isEmpty(bucketName)){
                        returnResponseResult(response,R.FAIL,"文件路径不正确");
                        return;
                    }
                    // 获取输入流和输出流
                    InputStream fileStream = sysFileService.downLoadFileNew(bucketName,minioPath.replace(bucketName+"/",""));
                    if(fileStream!=null){
                        if("1".equals(type)){
                            //预览
                        }else if("2".equals(type)){
                            //如果需要下载文件，去掉下面的注释
                            //response.setHeader("content-disposition", "attachment;");
                        }
                        OutputStream outputStream = response.getOutputStream();
                        int len = 0;
                        byte[] data = new byte[1024];
                        while ((len = fileStream.read(data)) != -1) {
                            outputStream.write(data, 0, len);
                        }
                        outputStream.close();
                        fileStream.close();
                    }
                }catch (Exception e){
                    e.printStackTrace();
                    log.error("获取文件流失败", e);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 图片转Base64(前端预览图片-小程序)
     * @param fileUrl   文件加密路径
     * @param type    type=1 预览，2=下载
     * @return
     */
    @RequestMapping("/previewFileBase64")
    public AjaxResult previewFileBase64(@RequestParam("fileUrl") String fileUrl, String type){
        //参数校验
        try {
            if(StringUtils.isEmpty(fileUrl)){
                return AjaxResult.error("文件路径不能为空");
            }else {
                try {
                    String minioPath= AESUtil_SC.decryptNoBase64(fileUrl,SysFileConstants.FILESECRET);
                    String bucketName= FileUploadUtils.getBucketName(minioPath);
                    if(StringUtils.isEmpty(bucketName)){
                        return AjaxResult.error("文件路径不正确");
                    }
                    String filename=minioPath.substring(minioPath.lastIndexOf("/")+1);
                    String sufx= filename.substring(filename.lastIndexOf(".")+1);
                    if(StringUtils.isEmpty(sufx)||!SysFileConstants.IMGTYPE.containsKey(sufx.toLowerCase())){
                        return AjaxResult.error("非图片类型");
                    }
                    // 获取输入流和输出流
                    InputStream fileStream = sysFileService.downLoadFileNew(bucketName,minioPath.replace(bucketName+"/",""));
                    if(fileStream!=null){
                        BufferedImage image = ImageIO.read(fileStream);
                        ByteArrayOutputStream stream = new ByteArrayOutputStream();
                        ImageIO.write(image, sufx.toLowerCase(), stream);
                        String base64 = "data:image/"+sufx.toLowerCase()+";base64,"+org.apache.axis.encoding.Base64.encode(stream.toByteArray());
                        return AjaxResult.success(base64);
                    }else{
                        return AjaxResult.error("文件不存在");
                    }
                }catch (Exception e){
                    e.printStackTrace();
                    log.error("获取文件失败", e);
                    return AjaxResult.error("获取文件失败："+e.getMessage());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("获取文件失败："+e.getMessage());
        }
    }

    public static void main(String[] args) throws Exception {
        System.out.println(AESUtil_SC.decryptNoBase64("29640d75a465436fb8b0a60cf10e332dad66a711e633328dd6e0d48d4774aea7da36ecb4a252163506f7a3f5b74f58f835cd8f8f12e2e0777ebd04b5c96a19c6241961b99924f3c90c455496cd4f73525530ef83e003f9146d34688f9e76d03dbe112ace761c81269b95db608c9f2fda", SysFileConstants.FILESECRET));
    }
    //@GetMapping("/filePreview/{filename}")
    public void  filePreview(ServletResponse response, @PathVariable("filename") String filename) throws Exception {
        if(StringUtils.isEmpty(filename)){
            throw  new Exception("文件名不能为空");//文件名不能为空
        }
        InputStream in=null;
        OutputStream out=null;
       try {
           String minioPath=AESUtil_SC.decryptNoBase64(filename,SysFileConstants.FILESECRET);
           String bucketName=FileUploadUtils.getBucketName(minioPath);
           if(StringUtils.isEmpty(bucketName)){
               throw  new Exception("文件路径不正确");//文件名不能为空
           }
           // 获取输入流和输出流
           in=minioUtils.getObject(bucketName,minioPath.replace(bucketName+"/",""));
           out = response.getOutputStream();
           //将输入流中的数据复制到输出流中
           byte[] buffer = new byte[1024];
           int len = 0;
           while ((len = in.read(buffer)) != -1) {
               out.write(buffer, 0, len);
           }
       }finally {
           // 关闭流和连接
           if(in!=null){
               in.close();
           }
           if(out!=null){
               out.close();
           }
       }
    }

    /**
     * 返回响应信息
     */
    private void returnResponseResult(ServletResponse response, int code, String msg) throws IOException {
        PrintWriter writer = null;
        OutputStreamWriter osw = null;
        try {
            osw = new OutputStreamWriter(response.getOutputStream(), "GBK");
            writer = new PrintWriter(osw, true);
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("code", code);
            jsonObject.put("message", msg);
            writer.write(jsonObject.toJSONString());
            writer.flush();
            writer.close();
            osw.close();
        } catch (Exception e) {
        } finally {
            if (null != writer) {
                writer.close();
            }
            if (null != osw) {
                osw.close();
            }
        }
    }

    /**
     * base64编码
     *
     * @param is
     * @return
     * @throws Exception
     */
    public static String inputStream2Base64(InputStream is) throws Exception {
        byte[] data = null;
        try {
            ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
            byte[] buff = new byte[100];
            int rc = 0;
            while ((rc = is.read(buff, 0, 100)) > 0) {
                swapStream.write(buff, 0, rc);
            }
            data = swapStream.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    throw new Exception("输入流关闭异常");
                }
            }
        }

        return Base64.getEncoder().encodeToString(data);
    }

    /**
     * 限制文件上传大小(不能超过20MB)
     * @param base64Str
     * @return
     */
    public double getFileSize(String base64Str) {
        //检测是否含有base64,文件头)
        if (base64Str.lastIndexOf(",") > 0) {
            base64Str = base64Str.substring(base64Str.lastIndexOf(",")+1);
        }
        // 获取base64字符串长度(不含data:audio/wav;base64,文件头)
        int size0 = base64Str.length();
        // 获取字符串的尾巴的最后10个字符，用于判断尾巴是否有等号，正常生成的base64文件'等号'不会超过4个
        String tail = base64Str.substring(size0 - 10);
        // 找到等号，把等号也去掉,(等号其实是空的意思,不能算在文件大小里面)
        int equalIndex = tail.indexOf("=");
        if (equalIndex > 0) {
            size0 = size0 - (10 - equalIndex);
        }
        // 计算后得到的文件流大小，单位为字节
        double reSize = size0 - ((double) size0 / 8) * 2;

        return reSize;
    }

    public String getcontentType(String fileName){
        String contentType=null;

        String suffix = "";
        String temp[]=fileName.split("\\.");
        if(temp.length>=2){
            suffix=temp[temp.length-1];
        }
        if (suffix=="") {
            contentType=null;
            return contentType;
        }
        switch (suffix){
            case "jpg": contentType="image/jpeg";break;
            case "jpeg": contentType="image/jpeg";break;
            case "png": contentType="image/png";break;
            case "txt": contentType="text/plain";break;
            case "md": contentType="application/octet-stream";break;
            case "sql": contentType="application/octet-stream";break;
            case "pdf": contentType="application/pdf";break;
            case "docx": contentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document";break;
            case "doc": contentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document";break;
            case "xls": contentType="application/vnd.ms-excel";break;
            case "xmind": contentType="application/octet-stream";break;
            case "lrc": contentType="application/octet-stream";break;

            default: contentType=suffix;
        }
        return contentType;

    }

    @GetMapping("/filePreview_bak/{filename}")
    public void  filePreview_bak(ServletResponse response, @PathVariable("filename") String filename) throws Exception {
        if(StringUtils.isEmpty(filename)){
           throw  new Exception("文件名不能为空");//文件名不能为空
        }
        String minioPath=AESUtil_SC.decrypt(filename,SysFileConstants.FILESECRET);
        // 创建一个URL对象，表示目标服务器的地址
        URL url = new URL("http://172.18.13.101:9000/chatfile/f7e31b2a-1ecf-491f-904e-c6444441fdbb/06411e60-9af5-11ee-873b-5daa422d84d2?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=lFqKQb4hlaAIbLjy%2F20231216%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20231216T120401Z&X-Amz-Expires=1800&X-Amz-SignedHeaders=host&X-Amz-Signature=22b3544f796643b9f4cf1c331299afee96cad9e4f60682f5d3ee77a14d9b8c2b");
         // 打开一个连接对象
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        // 设置连接属性
        conn.setRequestMethod("GET");
        conn.setDoInput(true);
        conn.setDoOutput(true);
        // 获取输入流和输出流
        InputStream in = conn.getInputStream();
        OutputStream out = response.getOutputStream();
        //将输入流中的数据复制到输出流中
        byte[] buffer = new byte[1024];
        int len = 0;
        while ((len = in.read(buffer)) != -1) {
            out.write(buffer, 0, len);
        }
        // 关闭流和连接
        in.close();
        out.close();
        conn.disconnect();
    }


}
